﻿using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncAWait语法糖
{
    class Program
    {
        static void Main(string[] args)
        {

            var r = GetTask();
            Console.WriteLine(r.Result);
            Console.WriteLine("=============================");
            Console.WriteLine(GetTask1().Result);
            Console.Read();

        }
        public static Task<string> GetTask()
        {
            Console.WriteLine("hellow world");
            // 主线程执行，底层还是会调用一个 AwaitUnsafeOnCompleted   委托给线程池，
            return Task.Run(() => {
               Console.WriteLine("工作线程");
               return "Jet";
            });
        }

        public static Task<string> GetTask1()
        {
            MyStateMachine machine = new MyStateMachine();
            machine.t_builder = AsyncTaskMethodBuilder<string>.Create();
            //TaskCompletionSource
            machine.state = -1;
            var t_builder = machine.t_builder;
            t_builder.Start(ref machine);
            return machine.t_builder.Task;

        }


    }

    public class MyStateMachine : IAsyncStateMachine
    {
        public AsyncTaskMethodBuilder<string> t_builder;
        // 状态机 一样的东西
        public int state;
        private MyStateMachine machine = null;
        private TaskAwaiter<string> myawaiter;
        string result = string.Empty;

        public MyStateMachine()
        {

        }
        public void MoveNext()
        {
            try
            {
                switch (state)
                {
                    case -1:
                        Console.WriteLine("hellow world");
                        var waiter = Task.Run(() => {
                            Console.WriteLine("工作线程");
                            return "jet";
                        }).GetAwaiter();
                        state = 0;  //设置下一个状态
                        myawaiter = waiter;
                        machine = this;
                        //丢给线程池执行了。。。
                        // 它里面还是会再调用  MoveNext
                        //private static void InvokeMoveNext(object stateMachine)
                        //{
                        //    ((IAsyncStateMachine)stateMachine).MoveNext();
                        //}
                        t_builder.AwaitUnsafeOnCompleted(ref waiter, ref machine);
                        break;
                    case 0:
                        var j = myawaiter.GetResult();
                        Console.WriteLine("我是结尾哦:{0}", j);
                        t_builder.SetResult(j);
                        break;
                }

            }
            catch (Exception ex)
            {
                t_builder.SetException(ex);  //设置t_builder的异常
            }
        }

        public void SetStateMachine(IAsyncStateMachine stateMachine)
        {
        }
    }

}
